package com.xiefengf.rabbitmq.consumer.service;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.xiefengf.rabbitmq.consumer.utils.StringUtils;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

/**
 * @author xiefengf
 * @version 1.0
 * @date 2024/1/10 23:58
 *
 *  过期消息消费类
 */

@Service
public class TtlConsumerService {

    /**
     * @RabbitHandler 代表此方法是一个消息接收的方法。该不要有返回值
     * @RabbitListener 可作用于类上，即是整个类被监听，作用于方法上，此方法监听
     * @param msg
     */
    @RabbitListener(queues = {StringUtils.DIRECT_TTL_QUEUE_NAME_1})
    @RabbitHandler
    public void ttl1Service(@Payload String msg,@Headers Map<String , Object> arguments,Message message, Channel channel) throws IOException {
        // 此处省略发邮件的逻辑
        try {
            System.out.println("ttl1-----msg--------->" + msg);
            System.out.println("ttl1-----arguments--------->" + arguments);
            // 确认消息
            // 第一个参数，交付标签，相当于消息ID 64位的长整数(从1开始递增)
            // 第二个参数，false表示仅确认提供的交付标签；true表示批量确认所有消息(消息ID小于自身的ID)，包括提供的交付标签
//            channel.basicQos(5);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 不确认消息   参数1：消息
            //            参数2： 是否应用于多消息
            //            参数3： 是否重新放回队列，否则丢弃或者进入死信队列
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            // 拒绝消息，  参数2： 是否重新放回队列，否则丢弃或者进入死信队列
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            // 两者区别：basicReject一次只能拒绝接收一个消息、basicNack方法可以支持一次0个或多个消息的拒收
        }

    }


    /**
     * @RabbitHandler 代表此方法是一个消息接收的方法。该不要有返回值
     * @RabbitListener 可作用于类上，即是整个类被监听，作用于方法上，此方法监听
     * @param msg
     */
    @RabbitListener(queues = {StringUtils.DIRECT_TTL_QUEUE_NAME_2})
    @RabbitHandler
    public void ttl2Service(@Payload String msg, @Headers Map<String , Object> arguments, Message message, Channel channel) throws IOException {
        // 此处省略发邮件的逻辑
        try {
            // 这里会走catch，就会拒绝消息，消息会到死信队列中
            System.out.println("消费失败" + msg);
            int i = 1/0;
            System.out.println("ttl2-----msg--------->" + msg);
            System.out.println("ttl2-----arguments--------->" + arguments);
            // 确认消息
            // 第一个参数，交付标签，相当于消息ID 64位的长整数(从1开始递增)
            // 第二个参数，false表示仅确认提供的交付标签；true表示批量确认所有消息(消息ID小于自身的ID)，包括提供的交付标签
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 不确认消息   参数1：消息
            //            参数2： 是否应用于多消息
            //            参数3： 是否重新放回队列，否则丢弃或者进入死信队列
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            // 拒绝消息，  参数2： 是否重新放回队列，否则丢弃或者进入死信队列
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            // 两者区别：basicReject一次只能拒绝接收一个消息、basicNack方法可以支持一次0个或多个消息的拒收
        }

    }

}
